﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;

[assembly: WebResource("EnhancedWebControls.ClientScripts.MultiSelectDropDownBehavior.js", "text/javascript")]
[assembly: WebResource("EnhancedWebControls.Resources.MultiSelectDropDownStyles.css", "text/css")]
[assembly: WebResource("EnhancedWebControls.Resources.CheckBoxChecked.png", "text/css")]
[assembly: WebResource("EnhancedWebControls.Resources.CheckBoxUnchecked.png", "text/css")]
[assembly: WebResource("EnhancedWebControls.Resources.ArrowButtonDown.png", "image/png")]
[assembly: WebResource("EnhancedWebControls.Resources.ArrowButtonDownHover.png", "image/png")]
[assembly: WebResource("EnhancedWebControls.Resources.ArrowButtonDownPressed.png", "image/png")]
namespace EnhancedWebControls
{
    [ToolboxData("<{0}:MultiSelectDropDown runat=server></{0}:MultiSelectDropDown>")]
    public class MultiSelectDropDown : ListControl, IPostBackDataHandler
    {
        #region Private Properties
            private List<string> CachedSelectedValues { get; set; }
            private string _defaultButtonImageUrl;
            private string _defaultButtonPressedImageUrl;
            private string _defaultButtonHoverImageUrl;
            private string _defaultCheckBoxUncheckedImageUrl;
            private string _defaultCheckBoxCheckedImageUrl;
        #endregion

        #region Public Properties
            public enum LabelModes
            {
                Off = 0,
                ShowAllItems = 1,
                ShowSelectedItems = 2
            }
            public IEnumerable<ListItem> SelectedItems
            {
                get
                {
                    return Items.Cast<ListItem>().Where(i => i.Selected);
                }
            }
            public IEnumerable<int> SelectedIndicies
            {
                get
                {
                    return SelectedItems.Select(i => Items.IndexOf(i));
                }
            }
            public override string SelectedValue
            {
                get
                {
                    if (RequiresDataBinding)
                        return CachedSelectedValues.FirstOrDefault();
                    else
                        return base.SelectedValue;
                }
                set
                {
                    AddSelectedValue(value,true);
                }
            }
            public IEnumerable<string> SelectedValues
            {
                get
                {
                    if (RequiresDataBinding)
                        return CachedSelectedValues;
                    else
                        return SelectedItems.Select(i => i.Value);
                }
                set
                {
                    ClearSelection();
                    foreach (string v in value)
                        AddSelectedValue(v);
                }
            }
            public bool DoNotListSelectedInTextBox { get; set; }
            public string EmptyMessage { get; set; }
            public string ButtonImageUrl { get; set; }
            public string ButtonPressedImageUrl { get; set; }
            public string ButtonHoverImageUrl { get; set; }
            public string CheckBoxUncheckedImageUrl { get; set; }
            public string CheckBoxCheckedImageUrl { get; set; }
            public bool HideSelectAllButton { get; set; }
            public bool HideDeselectAllButton { get; set; }
            public string SelectAllText { get; set; }
            public string DeselectAllText { get; set; }
            [Category("Appearance")]
            public Unit LabelWidth
            {
                get
                {
                    return (Unit)ViewState["LabelWidth"];
                }
                set
                {
                    ViewState["LabelWidth"] = value;
                }
            }
            /// <summary>
            /// Gets or Sets the width of the Field
            /// </summary>
            [Category("Appearance")]
            public Unit FieldWidth
            {
                get
                {
                    return (Unit)ViewState["FieldWidth"];
                }
                set
                {
                    ViewState["FieldWidth"] = value;
                }
            }
            /// <summary>
            /// Gets or Sets the width of the Field
            /// </summary>
            [Category("Appearance")]
            public Unit MaxHeight
            {
                get
                {
                    return (Unit)ViewState["MaxHeight"];
                }
                set
                {
                    ViewState["MaxHeight"] = value;
                }
            }
            public override Unit Width
            {
                get
                {
                    if ((LabelWidth.Type == FieldWidth.Type) && (LabelWidth.Type != UnitType.Percentage))
                        return new Unit(FieldWidth.Value + LabelWidth.Value, LabelWidth.Type);
                    else
                        return base.Width;
                }
                set
                {
                    base.Width = value;
                }
            }
            /// <summary>
            /// Gets or Sets the Text shown in the Label for the field
            /// </summary>
            [Category("Appearance"), DefaultValue(""), Localizable(true)]
            public string LabelText
            {
                get
                {
                    return (string)ViewState["LabelText"];
                }
                set
                {
                    ViewState["LabelText"] = value;
                }
            }
            /// <summary>
            /// Gets or Sets what type of label mode the control is in. The ShowAllItems and ShowSelectedItems LabelModes replace the field readonly representations of the values.
            /// </summary>
            [Category("Appearance"), DefaultValue(LabelModes.Off), Localizable(true)]
            public LabelModes LabelMode
            {
                get
                {
                    if (ViewState["LabelMode"] == null)
                        ViewState["LabelMode"] = LabelModes.Off;
                    return (LabelModes)ViewState["LabelMode"];
                }
                set
                {
                    ViewState["LabelMode"] = value;
                }
            }
            /// <summary>
            /// Gets or Sets whether the control is in ErrorMode. ErrorMode is usefull for highlighting a field that has not passed validation
            /// </summary>
            [Category("Appearance"), DefaultValue(false)]
            public bool ErrorMode { get; set; }
            [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
            public override ListItemCollection Items
            {
                get
                {
                    return base.Items;
                }
            }
        #endregion

        #region Public Helper Methods
            public string GetSelectedText()
            {
                StringBuilder rval = new StringBuilder();
                foreach (string s in SelectedItems.Select(i => i.Text))
                {
                    if (rval.ToString().Length > 0)
                        rval.Append(", ");
                    rval.Append(s);
                }
                return rval.ToString();
            }
            public void AddSelectedValue(string value)
            {
                AddSelectedValue(value, false);
            }
            public void AddSelectedValue(string value, bool clearSelections)
            {
                ListItem item = Items.FindByValue(value);
                if (item != null)
                {
                    if (clearSelections)
                        this.ClearSelection();
                    item.Selected = true;
                }
                else if (!CachedSelectedValues.Contains(value))
                {
                    if (RequiresDataBinding)
                    {
                        if (clearSelections)
                        {
                            this.ClearSelection();
                            CachedSelectedValues.Clear();
                        }
                        CachedSelectedValues.Add(value);
                    }
                }
            }
        #endregion

        #region Override or Interface Methods
            public MultiSelectDropDown()
                : base()
            {
                CachedSelectedValues = new List<string>();
                LabelWidth = new Unit(100, UnitType.Pixel);
                FieldWidth = new Unit(180, UnitType.Pixel);
                MaxHeight = new Unit(0, UnitType.Pixel);
                SelectAllText = "Select All";
                DeselectAllText = "Clear Selection";
            }
            public override void DataBind()
            {
                base.DataBind();
                foreach (string s in CachedSelectedValues)
                    AddSelectedValue(s);
                CachedSelectedValues.Clear();
            }
            protected override void OnPreRender(EventArgs e)
            {
                EnsureChildControls();
                base.OnPreRender(e);
                if (Visible)
                {
                    ApplyDefaultImages();
                    if (Enabled)
                        ApplyClientScriptsToPage();
                    Page.RegisterRequiresPostBack(this);
                }
                if (LabelWidth.Type != UnitType.Pixel || FieldWidth.Type != UnitType.Pixel)
                    throw new NotSupportedException("This control does not support width types other than Pixel");
            }
            public override void RenderBeginTag(HtmlTextWriter output)
            {
                RenderDesignTimeStyles(output);
                output.AddAttribute("id", this.ClientID);
                output.AddAttribute("Name", "MultiSelectContainer");
                Style["display"] = "block";
                if (string.IsNullOrEmpty(Style["float"]))
                    Style["float"] = "left";
                if (string.IsNullOrEmpty(Style["clear"]))
                    Style["clear"] = "both";
                if (string.IsNullOrEmpty(Style["padding"]))
                    Style["padding"] = "1px 0px 1px 0px";
                Style["width"] = (new Unit(FieldWidth.Value + LabelWidth.Value, UnitType.Pixel)).ToString();
                if (!string.IsNullOrEmpty(CssClass))
                    output.AddAttribute("class", CssClass);
                else
                    output.AddAttribute("class", "MultiSelectContainer");
                foreach (string k in Style.Keys)
                {
                    output.AddStyleAttribute(k, Style[k]);
                }

                output.RenderBeginTag(HtmlTextWriterTag.Div);
            }
            protected override void Render(HtmlTextWriter output)
            {
                EnsureChildControls();
                RenderBeginTag(output);
                RenderContents(output);
                RenderEndTag(output);
            }
            protected override void RenderContents(HtmlTextWriter output)
            {

                string postBackOnChangeUniqueId = "";
                if (AutoPostBack)
                    postBackOnChangeUniqueId = UniqueID;
                output.AddAttribute("type", "hidden");
                output.AddAttribute("name", "PostBackOnChangeUniqueId");
                output.AddAttribute("id", ClientID + "_PostBackOnChangeUniqueId");
                output.AddAttribute("value", postBackOnChangeUniqueId);
                output.RenderBeginTag(HtmlTextWriterTag.Input);
                output.RenderEndTag();

                if (LabelWidth.Value > 0)
                {
                    output.AddStyleAttribute("display", "block");
                    output.AddStyleAttribute("float", "left");
                    output.AddStyleAttribute("clear", "none");
                    output.AddStyleAttribute("min-height", "10px");
                    if (FieldWidth.Value > 0)
                        output.AddStyleAttribute("width", LabelWidth.ToString());
                    if (!string.IsNullOrEmpty(ToolTip))
                        output.AddAttribute("title", ToolTip);
                    output.RenderBeginTag(HtmlTextWriterTag.Div);

                    output.WriteBeginTag("label");
                    if (Enabled && ErrorMode && (LabelMode == LabelModes.Off))
                        output.WriteAttribute("class", "MultiSelect__ErrorLabel");
                    else
                        output.WriteAttribute("class", "MultiSelect__Label");
                    output.WriteAttribute("for", this.ClientID + "_InputField");
                    output.Write(HtmlTextWriter.TagRightChar);
                    output.WriteEncodedText(LabelText);
                    output.WriteEndTag("label");

                    output.RenderEndTag();
                    output.WriteLine();
                }
                output.AddStyleAttribute("display", "block");
                output.AddStyleAttribute("float", "left");
                output.AddStyleAttribute("clear", "none");
                if (FieldWidth.Value > 0)
                    output.AddStyleAttribute("width", FieldWidth.ToString());
                output.RenderBeginTag(HtmlTextWriterTag.Div);

                if (LabelMode == LabelModes.Off)
                    RenderActiveContents(output);
                else
                    RenderStaticContents(output);
            
                output.RenderEndTag();
            }
            public override void RenderEndTag(HtmlTextWriter output)
            {
                EnsureChildControls();
                output.RenderEndTag();
            }
            protected override void OnInit(EventArgs e)
            {
                base.OnInit(e);
                if (!DesignMode && ((System.Web.UI.HtmlControls.HtmlHead)Page.Header).FindControl("MultiSelectDefaultStyleSheet") == null)
                {
                    string cssLink = "<link href=\"" + Page.ClientScript.GetWebResourceUrl(this.GetType(), "EnhancedWebControls.Resources.MultiSelectDropDownStyles.css") + "\" type=\"text/css\" rel=\"stylesheet\" />";
                    LiteralControl lc = new LiteralControl(cssLink);
                    lc.ID = "MultiSelectDefaultStyleSheet";
                    ((System.Web.UI.HtmlControls.HtmlHead)Page.Header).Controls.Add(lc);
                }

                _defaultButtonImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "EnhancedWebControls.Resources.ArrowButtonDown.png");
                _defaultButtonPressedImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "EnhancedWebControls.Resources.ArrowButtonDownPressed.png");
                _defaultButtonHoverImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "EnhancedWebControls.Resources.ArrowButtonDownHover.png");
                _defaultCheckBoxUncheckedImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "EnhancedWebControls.Resources.CheckBoxUnchecked.png");
                _defaultCheckBoxCheckedImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "EnhancedWebControls.Resources.CheckBoxChecked.png");
                DataBind();
            }
            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
                DataBind();
            }
            public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
            {
                IEnumerable<int> newSelectedIndicies = postCollection.AllKeys
                    .Where(x => x != null && x.StartsWith(ClientID + this.ClientIDSeparator + "CheckBox") && postCollection[x] == "on")
                    .Select(x => Convert.ToInt32(x.Replace(ClientID + this.ClientIDSeparator + "CheckBox", "")));

                if (!newSelectedIndicies.OrderBy(x => x).SequenceEqual(SelectedIndicies.OrderBy(x => x)))
                {
                    for(int i = 0; i < Items.Count;i++)
                    {
                        Items[i].Selected = newSelectedIndicies.Contains(i);
                    }
                    return true; 
                }
                else
                    return false; 
            }
            public void RaisePostDataChangedEvent()
            {
                OnSelectedIndexChanged(new EventArgs());
            }
        #endregion

        #region Private Helper Methods
            private void RenderStaticContents(HtmlTextWriter output)
            {
                output.AddStyleAttribute("width", FieldWidth.ToString());
                output.AddStyleAttribute("padding-top", "2px");
                output.RenderBeginTag(HtmlTextWriterTag.Div);
                foreach (ListItem i in Items)
                {

                    int index = Items.IndexOf(i);
                    output.AddAttribute("type", "checkbox");
                    output.AddAttribute("id", ClientID + this.ClientIDSeparator + "CheckBox" + index);
                    output.AddAttribute("name", ClientID + this.ClientIDSeparator + "CheckBox" + index);
                    if (i.Selected)
                        output.AddAttribute("checked", "checked");
                    output.AddStyleAttribute("display", "none");
                    output.RenderBeginTag(HtmlTextWriterTag.Input);
                    output.RenderEndTag();
                    output.WriteLine();
                    if (i.Selected || (LabelMode == LabelModes.ShowAllItems))
                    {         
                        output.WriteBeginTag("div");
                        output.WriteAttribute("class", "MultiSelect__LabelModeItemText");
                        output.Write(HtmlTextWriter.SpaceChar + "style" + HtmlTextWriter.EqualsChar + HtmlTextWriter.DoubleQuoteChar);
                        if (LabelMode == LabelModes.ShowAllItems)
                        {
                            output.WriteStyleAttribute("width", new Unit(FieldWidth.Value - 21).ToString());
                            if (i.Selected)
                                output.WriteStyleAttribute("background-image", "url(" + CheckBoxCheckedImageUrl + ")");
                            else
                                output.WriteStyleAttribute("background-image", "url(" + CheckBoxUncheckedImageUrl + ")");
                            output.WriteStyleAttribute("background-repeat", "no-repeat");
                            output.WriteStyleAttribute("padding-left", "21px");
                            output.WriteStyleAttribute("min-height", "17px");
                        }
                        else
                            output.WriteStyleAttribute("width", FieldWidth.ToString());
                        output.Write(HtmlTextWriter.DoubleQuoteChar);
                        output.Write(HtmlTextWriter.TagRightChar);
                        output.WriteEncodedText(i.Text);
                        output.WriteEndTag("div");
                    }
                }
                output.RenderEndTag();
            }
            private void RenderActiveContents(HtmlTextWriter output)
            {
                    if (Enabled)
                {
                    if (ErrorMode)
                        output.AddAttribute("class", "MultiSelect__ErrorControl");
                    else
                        output.AddAttribute("class", "MultiSelect__EnabledControl");
                }
                else
                    output.AddAttribute("class", "MultiSelect__DisabledControl");
                output.AddStyleAttribute("width", new Unit(FieldWidth.Value - 2).ToString());
                output.AddStyleAttribute("clear", "none");
                output.RenderBeginTag(HtmlTextWriterTag.Div);

                output.AddAttribute("class", "MultiSelect__InputContainer");
                output.AddStyleAttribute("width", new Unit(FieldWidth.Value - 26).ToString()); //(26 = padding(2) + parentBorder(2) + button(22)
                output.RenderBeginTag(HtmlTextWriterTag.Div);

                output.AddAttribute("type", "text");
                output.AddAttribute("id", this.ClientID + "_InputField");
                output.AddStyleAttribute("border", "none");
                output.AddStyleAttribute("margin", "0px");
                output.AddStyleAttribute("padding", "0px");
                output.AddStyleAttribute("width", "100%");
                output.AddStyleAttribute("height", "100%");
                output.AddAttribute("readonly", "readonly");
                string selectedText = GetSelectedText();
                if (!string.IsNullOrEmpty(selectedText) && !DoNotListSelectedInTextBox)
                {
                    output.AddAttribute("value", selectedText);
                    output.AddAttribute("title", selectedText);
                    output.AddAttribute("class", "MultiSelect__TextBox");
                }
                else
                {
                    output.AddAttribute("value", EmptyMessage);
                    output.AddAttribute("title", EmptyMessage);
                    output.AddAttribute("class", "MultiSelect__TextBox MultiSelect__EmptyTextBox");
                }
                if (!Enabled)
                    output.AddAttribute("disabled", "disabled");
                output.RenderBeginTag(HtmlTextWriterTag.Input);
                output.RenderEndTag();

                output.RenderEndTag();
                output.WriteLine();

                output.WriteBeginTag("div");
                output.AddAttribute("title", selectedText);
                if (Enabled)
                    output.WriteAttribute("class", "MultiSelect__EnabledButton");
                else
                    output.WriteAttribute("class", "MultiSelect__DisabledButton");

                output.WriteAttribute("name", "ActivateButton");
                output.Write(HtmlTextWriter.SpaceChar + "style" + HtmlTextWriter.EqualsChar + HtmlTextWriter.DoubleQuoteChar);
                if (Enabled)
                    output.WriteStyleAttribute("cursor", "pointer");
                output.WriteStyleAttribute("background-image", "url(" + ButtonImageUrl + ")");
                output.Write(HtmlTextWriter.DoubleQuoteChar);
                output.Write(HtmlTextWriter.TagRightChar);
                output.WriteEndTag("div");

                output.RenderEndTag();
                output.WriteLine();

                //if (Enabled)
                    RenderDropDownSection(output);

                RenderPreloadImages(output);
            }
            private void RenderDropDownSection(HtmlTextWriter output)
            {
                output.AddStyleAttribute("float", "left");
                output.AddStyleAttribute("clear", "both");
                output.RenderBeginTag(HtmlTextWriterTag.Div);
                output.AddStyleAttribute("position", "absolute");
                output.AddStyleAttribute("z-index", "999");
                output.RenderBeginTag(HtmlTextWriterTag.Div);
                output.AddStyleAttribute("position", "relative");
                output.AddStyleAttribute("top", "-1px");
                output.AddStyleAttribute("z-index", "999");
                output.RenderBeginTag(HtmlTextWriterTag.Div);
                output.AddAttribute("class", "MultiSelect__ListContainer");
                output.AddAttribute("name", "ListContainer");
                output.AddStyleAttribute("min-width", new Unit(FieldWidth.Value - 2).ToString());
                if (MaxHeight.Value > 0)
                {
                    output.AddStyleAttribute("max-height", MaxHeight.ToString());
                    output.AddStyleAttribute("overflow", "auto");
                }
                output.RenderBeginTag(HtmlTextWriterTag.Div);
                
                if (!HideSelectAllButton || !HideDeselectAllButton)
                {
                    output.AddAttribute("class", "MultiSelect__CommandRow");
                    output.AddStyleAttribute("min-width", new Unit(FieldWidth.Value - 2).ToString());
                    output.RenderBeginTag(HtmlTextWriterTag.Div);
                    if (!HideSelectAllButton)
                    {
                        output.WriteBeginTag("div");
                        output.WriteAttribute("class", "MultiSelect__SelectAllCommand");
                        output.Write(HtmlTextWriter.TagRightChar);
                        output.WriteEncodedText(SelectAllText);
                        output.WriteEndTag("div");

                        if (!HideDeselectAllButton)
                        {
                            output.WriteLine();
                            output.WriteBeginTag("div");
                            output.WriteAttribute("class", "MultiSelect__CommandSeperator");
                            output.Write(HtmlTextWriter.TagRightChar);
                            output.WriteEndTag("div");
                            output.WriteLine();
                        }
                    }

                    if (!HideDeselectAllButton)
                    {
                        output.WriteBeginTag("div");
                        output.WriteAttribute("class", "MultiSelect__ClearCommand");
                        output.Write(HtmlTextWriter.TagRightChar);
                        output.WriteEncodedText(DeselectAllText);
                        output.WriteEndTag("div");
                    }

                    output.RenderEndTag();
                    output.WriteLine();
                }

                foreach (ListItem i in this.Items)
                {
                    RenderListItem(output, i);
                }

                output.RenderEndTag();
                output.RenderEndTag();
                output.RenderEndTag();
                output.RenderEndTag();
            }
            private void RenderListItem(HtmlTextWriter output, ListItem i)
            {

                int index = Items.IndexOf(i);
                output.AddAttribute("class", "MultiSelect__ListItem");
                output.AddStyleAttribute("min-width", new Unit(FieldWidth.Value - 2).ToString());
                output.AddStyleAttribute("cursor", "pointer");
                output.RenderBeginTag(HtmlTextWriterTag.Div);

                output.AddAttribute("type", "checkbox");
                //output.AddAttribute("visible", "false");
                output.AddAttribute("id", ClientID + this.ClientIDSeparator + "CheckBox" + index);
                output.AddAttribute("name", ClientID + this.ClientIDSeparator + "CheckBox" + index);
                if (i.Selected)
                    output.AddAttribute("checked", "checked");
                output.AddStyleAttribute("display", "none");
                output.RenderBeginTag(HtmlTextWriterTag.Input);
                output.RenderEndTag();
                output.WriteLine();

                output.WriteBeginTag("div");
                output.WriteAttribute("class", "MultiSelect__CheckBox");
                output.Write(HtmlTextWriter.SpaceChar + "style" + HtmlTextWriter.EqualsChar + HtmlTextWriter.DoubleQuoteChar);
                if (i.Selected)
                    output.WriteStyleAttribute("background-image", "url(" + CheckBoxCheckedImageUrl + ")");
                else
                    output.WriteStyleAttribute("background-image", "url(" + CheckBoxUncheckedImageUrl + ")");
                output.Write(HtmlTextWriter.DoubleQuoteChar);
                output.Write(HtmlTextWriter.TagRightChar);
                output.WriteEndTag("div");
                output.WriteLine();

                output.WriteBeginTag("div");
                output.WriteAttribute("class", "MultiSelect__ItemText");
                output.Write(HtmlTextWriter.SpaceChar + "style" + HtmlTextWriter.EqualsChar + HtmlTextWriter.DoubleQuoteChar);
                output.WriteStyleAttribute("min-width", new Unit(FieldWidth.Value - 21).ToString());
                output.Write(HtmlTextWriter.DoubleQuoteChar);
                output.Write(HtmlTextWriter.TagRightChar);
                output.WriteEncodedText(i.Text);
                output.WriteEndTag("div");

                output.RenderEndTag();
                if (index + 1 < Items.Count)
                    output.WriteLine();
            }
            private void RenderPreloadImages(HtmlTextWriter output)
            {
                var images = new[] {
                    new {ClientID = ClientID + "_ImgChecked", Url = CheckBoxCheckedImageUrl}, 
                    new {ClientID = ClientID + "_ImgUnchecked", Url = CheckBoxUncheckedImageUrl}, 
                    new {ClientID = ClientID + "_ImgButton", Url = ButtonImageUrl},
                    new {ClientID = ClientID + "_ImgHover", Url = ButtonHoverImageUrl},
                    new {ClientID = ClientID + "_ImgPressed", Url = ButtonPressedImageUrl}};
                foreach (var s in images)
                {
                    output.WriteBeginTag("div");
                    output.WriteAttribute("ID", s.ClientID);
                    output.Write(HtmlTextWriter.SpaceChar + "style" + HtmlTextWriter.EqualsChar + HtmlTextWriter.DoubleQuoteChar);
                    output.WriteStyleAttribute("background-image", "url(" + s.Url + ")");
                    output.WriteStyleAttribute("display", "none");
                    output.Write(HtmlTextWriter.DoubleQuoteChar);
                    output.Write(HtmlTextWriter.TagRightChar);
                    output.WriteEndTag("div");
                    output.WriteLine();
                }
            }
            private void ApplyDefaultImages()
            {
                bool buttonImageProvided = true;
                if (string.IsNullOrEmpty(ButtonImageUrl))
                {
                    ButtonImageUrl=_defaultButtonImageUrl;
                    buttonImageProvided = false;
                }
                if (string.IsNullOrEmpty(ButtonPressedImageUrl))
                {
                    if (buttonImageProvided) //if button provided but pressed is not then make static image
                        ButtonPressedImageUrl = ButtonImageUrl;
                    else
                    {
                        ButtonPressedImageUrl = _defaultButtonPressedImageUrl;
                    }
                }
                if (string.IsNullOrEmpty(ButtonHoverImageUrl))
                {
                    if (buttonImageProvided) //if button provided but hover is not then make static image
                        ButtonHoverImageUrl = ButtonImageUrl;
                    else
                    {
                        ButtonHoverImageUrl = _defaultButtonHoverImageUrl;
                    }
                }
                if (string.IsNullOrEmpty(CheckBoxUncheckedImageUrl))
                {
                    CheckBoxUncheckedImageUrl = _defaultCheckBoxUncheckedImageUrl;
                }
                if (string.IsNullOrEmpty(CheckBoxCheckedImageUrl))
                {
                    CheckBoxCheckedImageUrl = _defaultCheckBoxCheckedImageUrl;
                } 
            }
            private void ApplyClientScriptsToPage()
            {
                //bind events - this will be rendered for each unique multidropdown
                ScriptManager.RegisterClientScriptResource(this, this.GetType(), "EnhancedWebControls.ClientScripts.MultiSelectDropDownBehavior.js");
                ScriptManager.RegisterStartupScript(Page, this.GetType(), ClientID + "_MultiSelectStartup", GetStartupScript(), true);
            }
            private string GetStartupScript()
            {
                StringBuilder startupScript = new StringBuilder();
                startupScript.AppendLine("$(document).ready(function () {");
                startupScript.AppendLine("var ContainerItem = $('#{CLIENTID}');");
                startupScript.AppendLine("ContainerItem.find('[name=ActivateButton]:first').hover(");
                startupScript.AppendLine("function () {$(this).css('background-image',$('#{CLIENTID}_ImgHover').css('background-image')); },");
                startupScript.AppendLine("function () {$(this).css('background-image',$('#{CLIENTID}_ImgButton').css('background-image')); })");
                startupScript.AppendLine(".mousedown(function () {$(this).css('background-image',$('#{CLIENTID}_ImgPressed').css('background-image')); })");
                startupScript.AppendLine(".mouseup(function () {$(this).css('background-image',$('#{CLIENTID}_ImgButton').css('background-image')); })");
                startupScript.AppendLine(".click(function (event) { HandleDropDownEvent(this, event); });");
                startupScript.AppendLine("ContainerItem.find('input:text').click(function (event) { HandleDropDownEvent(this, event); });");
                startupScript.AppendLine("ContainerItem.find('[name=ListContainer] div.MultiSelect__ListItem').click(function (event) { HandleSelectItemClickEvent(this, event, '{EmptyMessage}',{doNotList}); });");
                if (!HideSelectAllButton || !HideDeselectAllButton)
                {
                    startupScript.AppendLine("ContainerItem.find('.MultiSelect__CommandRow').click(function (event) {event.stopPropagation();});");
                    startupScript.AppendLine("ContainerItem.find('.MultiSelect__SelectAllCommand').click(function (event) {HandleSelectAllEvent(this,event,{doNotList})});");
                    startupScript.AppendLine("ContainerItem.find('.MultiSelect__ClearCommand').click(function (event) {HandleClearEvent(this,event, '{EmptyMessage}',{doNotList})});");
                }
                startupScript.AppendLine("});");
                return startupScript.ToString().Replace("{CLIENTID}", ClientID).Replace("{EmptyMessage}", EmptyMessage).Replace("{doNotList}", DoNotListSelectedInTextBox.ToString().ToLower());
            }
            private void RenderDesignTimeStyles(HtmlTextWriter output)
            {
                if (DesignMode)
                {
                    using (StreamReader reader = new StreamReader(this.GetType().Assembly.GetManifestResourceStream(this.GetType(), "Resources.MultiSelectDropDownStyles.css")))
                    {
                        string styleTag = "<style type=\"text/css\">" + reader.ReadToEnd() + "</style>";
                        reader.Close();
                        LiteralControl lc = new LiteralControl(styleTag);
                        lc.ID = "MultiSelectDefaultInlineStyleSheet";
                        lc.RenderControl(output);
                    }
                }
            }
        #endregion
    }
}
